class TG_BotController extends UdkBot;
var Pawn HuntedPawn;
var Vector TempDest, TempOffset, TempFinal, PastEndPoint;
var     float   OffsetToHero;
var int PastDecision;

//*----------------------------------------------------------
//* TraceToAvoidPawns
//*----------------------------------------------------------
/**
* Returns VECTOR that should help avoiding Pawns
*
* @param StartPoint is the point where the Trace will Start From
* @param EndPoint is the point where the Trace will Stop tracing
*
*/

simulated function vector TraceToAvoidPawns(Vector StartPoint ,Vector EndPoint)
{
	local Actor HitActor,DirectionActor, LHA,RHA;
	local Vector AddVector , HitNormal, HitLocation, MovePosition,LHN,LHL,RHL,RHN;
	local Int Decision,Direction;
	local float StrafeSize, Bonus;
	local bool LeftTrace,RightTrace,IsWall;
	
	if(PastEndPoint != Endpoint)
	{
	Decision = RandRange (1,2);
	PastDecision = Decision;
	PastEndPoint = EndPoint;
	}
	else
	{
	Decision = PastDecision;
	}	
	
		switch (Decision)
		{
		case 1:
			Direction = -1;//Direction  = Left
			break;
		case 2:
			Direction = 1; //Direction  = Right
			break;
		}

	ForEach TraceActors(class'Actor', HitActor, HitLocation, HitNormal, EndPoint, StartPoint, Pawn.GetCollisionExtent())
	{
	   if ( HitActor.ClassIsChildOf(HitActor.Class, Class'TG_BotPawn') && HitActor != Self  )
	   {
	   	ForEach TraceActors(class'Actor', LHA, LHL, LHN,HitActor.Location , HitActor.Location, Pawn.GetCollisionExtent())
		{
				if ( LHA.ClassIsChildOf(HitActor.Class, Class'UDKPAWN') && HitActor != Self  )
				{
					IsWall = false;
					LeftTrace = false;
				}
				else if ( LHA.bWorldGeometry)
				{
					IsWall = true;
					LeftTrace = true;	
				}
				else
				{
					IsWall = false;
					LeftTrace = true;	
				}
		}
	   	ForEach TraceActors(class'Actor', RHA, RHL, RHN,HitActor.Location , HitActor.Location, Pawn.GetCollisionExtent())
		{
				if ( RHA.ClassIsChildOf(HitActor.Class, Class'UDKPAWN') && HitActor != Self  )
				{
					IsWall = false;
					RightTrace = true;
				}
				else if ( RHA.bWorldGeometry)
				{
					IsWall = true;
					RightTrace = true;	
				}
				else
				{
					IsWall = false;
					RightTrace = false;	
				}
		}
		
		LeftTrace  =  FastTrace(HitActor.Location , HitActor.Location);
		RightTrace =  FastTrace(HitActor.Location , HitActor.Location);
		StrafeSize =  ((Tg_BotPawn(HitActor).GetCollisionRadius() *1.5) + Pawn.GetCollisionRadius());
			if(RightTrace && !LeftTrace)
			{
				worldinfo.game.broadcast(self, "Left Direction");
				Direction = -1;
				MovePosition = 0;//Presmatqne
				PastDecision = 1;
			}
			else if(LeftTrace && !RightTrace)
			{
				worldinfo.game.broadcast(self, "Right Direction");
				Direction = 1;
				MovePosition = 0;//Presmatqne
				PastDecision = 2;
			}
			else if((RightTrace && LeftTrace) || (!RightTrace && !LeftTrace))
			{
				worldinfo.game.broadcast(self, "Use Decision and Go a Direction");
				MovePosition = 0;//Presmatqne
			}
			else
			{
				worldinfo.game.broadcast(self, "Something Wrong");
				MovePosition = EndPoint;
			}
			return MovePosition;
		}
		else
		{
			worldinfo.game.broadcast(self, "Nothing Infront");
			return EndPoint;
		}
	}
}
simulated function vector TraceToAvoidObstacle( vector Point , optional int iOffset, optional float TraceDistanceModifier)
{
local Actor HitActor;
local Vector HitLocation, HitNormal, StrafeVector, vEyesLocation, vCollisionExtent, TraceEndLeft, TraceEndRight;
local float TraceSize, SizeR, SizeL, BlockingDistance, StrafeSize;

vEyesLocation = Location;
//vEyesLocation = Mesh.GetBoneLocation('b_head')+Normal(Vector(Rotat ion))*15;

vCollisionExtent.X = 2;
vCollisionExtent.Y = 2 + Pawn.GetCollisionRadius();
vCollisionExtent.Z = 2;

if (TraceDistanceModifier<= 0.)
TraceDistanceModifier= 1000000;

TraceSize = Pawn.GetCollisionRadius()*TraceDistanceModifier;

if (TraceSize > VSize(Point-Location) )
TraceSize = VSize(Point-Location);

//Determine how close blocking actor is
ForEach TraceActors(class'Actor', HitActor, HitLocation, HitNormal, Location+Normal(Point-Location)*TraceSize, vEyesLocation, vCollisionExtent)
{
if (HitActor.bWorldGeometry || ( HitActor.ClassIsChildOf(HitActor.Class, Class'TG_BotPawn') && HitActor != Self ) )
{
BlockingDistance = VSize(HitLocation-vEyesLocation);
break;
}
}
if (HitActor == none){
DrawDebugLine(vEyesLocation,Location+Normal(Point-Location)*TraceSize,0,255,0,false);
return Vect(0.,0.,0.);
}
HitActor = none;

//Go backward if obstacle is too big
if (iOffset > 50 ){
DrawDebugLine(vEyesLocation,Location+Normal(Location-Point)*TraceSize,0,255,0,false);
return Normal(Location-Point)*2; //multiply to 2 to wrap over current velocity/acceleration
}

DrawDebugLine(vEyesLocation,HitLocation,255,0,0,false);

StrafeSize = Pawn.GetCollisionRadius()*4/BlockingDistance+4;
// If obstacle is too close - strafe backward
if (StrafeSize>1.)
return Normal(Location-Point)*2;

if (iOffset <= 0)
iOffset = 1;

StrafeVector = Normal( Normal(HitLocation-Location) cross vect(0, 0, 1) )*Pawn.GetCollisionRadius()*iOffset;

TraceEndRight = Location+Normal(HitLocation+StrafeVector-Location)*VSize(Point - Location)*2;

TraceEndLeft = Location+Normal(HitLocation-StrafeVector-Location)*VSize(Point - Location)*2;

StrafeVector = Vect(0.,0.,0.);

ForEach TraceActors(class'Actor', HitActor, HitLocation, HitNormal, TraceEndRight, vEyesLocation, vCollisionExtent)
{
if (HitActor.bWorldGeometry || ( HitActor.ClassIsChildOf(HitActor.Class, Class'Pawn') && HitActor != Self ) )
{
DrawDebugLine(vEyesLocation,HitLocation,0,0,255,false);
SizeR = VSize(HitLocation-Location);
break;
}
}
ForEach TraceActors(class'Actor', HitActor, HitLocation, HitNormal, TraceEndLeft, vEyesLocation, vCollisionExtent)
{
if (HitActor.bWorldGeometry || ( HitActor.ClassIsChildOf(HitActor.Class, Class'Pawn') && HitActor != Self ) )
{
DrawDebugLine(vEyesLocation,HitLocation,0,0,255,false);
SizeL = VSize(HitLocation-Location);
break;
}
}
if (HitActor != none && ABS(SizeR-SizeL) > 0.)
{

if (SizeR > SizeL){
//DrawDebugLine(vEyesLocation,TraceEndLeft,255,0,0,t rue);
//DrawDebugLine(vEyesLocation,TraceEndRight,0,255,25 5,true);

StrafeVector = Normal(TraceEndRight);
}
else{

//DrawDebugLine(vEyesLocation,TraceEndRight,255,0,0, true);
//DrawDebugLine(vEyesLocation,TraceEndLeft,0,255,255 ,true);

StrafeVector = Normal(TraceEndLeft);

}
}
else
StrafeVector = TraceToAvoidObstacle(Point,iOffset+3);

return StrafeVector;


}

auto state Idle
{
	event SeePlayer(Pawn SeenPlayer)
	{
	HuntedPawn = SeenPlayer;
	GoToState('Moving');
	}
	Begin:
	HuntedPawn = none;
	Pawn.Velocity = vect(0,0,0);
	bPreciseDestination=false;
    //worldinfo.game.broadcast(self, "I ARE DUMB");
}


state Moving
{
    ignores SeePlayer;
    function bool FindNavMeshPath() 
    {
        `log("FindNavMeshPath() Fired");
 
        NavigationHandle.PathConstraintList = none;
        NavigationHandle.PathGoalList = none;
 
        class'NavMeshPath_Toward'.static.TowardGoal(NavigationHandle, HuntedPawn);
        class'NavMeshGoal_At'.static.AtActor(NavigationHandle, HuntedPawn, 32);
 
        return NavigationHandle.FindPath();
    }
Begin:
    GetALocalPlayerController().Pawn;
    
		if(FindNavMeshPath()) 
        {
            NavigationHandle.SetFinalDestination(HuntedPawn.Location);
            FlushPersistentDebugLines();
            NavigationHandle.DrawPathCache(,TRUE);
            if(NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()) && HuntedPawn.Health > 0 && HuntedPawn != none && (50 < (VSize(HuntedPawn.Location - Pawn.Location))))
			{	
                DrawDebugLine(Pawn.Location, TempDest, 255, 0, 0, true);
                DrawDebugSphere(TempDest,16,20,255,0,0,true);
				worldinfo.game.broadcast(self, "movement");	
                //MoveTo(TempDest);
				MoveTo( TempDest, HuntedPawn, 150, false );
            }
            else
            {
            	worldinfo.game.broadcast(self, "I ARE DUMB");
				GotoState('Idle');
            }
        }
        
        else
        {
        	`log("build NavMesh");
        	
            GotoState('Idle');
        }
    goto 'Begin';
}	



DefaultProperties
{
		OffsetToHero=75;
}
